package channelService

import (
	"net"
	"sync"
)

type ChannelManager struct {
	skt2ctx sync.Map
	skt2key sync.Map
	key2ctx sync.Map
}

func (e *ChannelManager) getServiceKeys() *map[string]interface{} {
	keys := make(map[string]interface{})
	e.key2ctx.Range(func(key, ctx interface{}) bool {
		keys[key.(string)] = ctx
		return true
	})

	return &keys
}

func (e *ChannelManager) setServiceKey(ctx net.Conn, serviceKey string) {
	e.skt2ctx.Store(ctx.RemoteAddr().String(), ctx)
	e.skt2key.Store(ctx.RemoteAddr().String(), serviceKey)
	e.key2ctx.Store(serviceKey, ctx)
}

func (e *ChannelManager) getContextByServiceKey(serviceKey string) net.Conn {
	val, ok := e.key2ctx.Load(serviceKey)
	if !ok {
		return nil
	}

	return val.(net.Conn)
}

func (e *ChannelManager) getServiceKeyByRemoteAddr(sktAddr string) string {
	val, ok := e.skt2key.Load(sktAddr)
	if !ok {
		return ""
	}

	return val.(string)
}

func (e *ChannelManager) getContextByRemoteAddr(sktAddr string) net.Conn {
	val, ok := e.skt2ctx.Load(sktAddr)
	if !ok {
		return nil
	}
	return val.(net.Conn)
}

func (e *ChannelManager) removeByRemoteAddr(sktAddr string) {
	key, ok := e.skt2key.Load(sktAddr)
	if ok {
		e.key2ctx.Delete(key)
	}

	e.skt2ctx.Delete(sktAddr)
	e.skt2key.Delete(sktAddr)
}

func (e *ChannelManager) removeByServiceKey(serviceKey string) {
	val, ok := e.key2ctx.Load(serviceKey)
	if ok {
		ctx := val.(net.Conn)
		adrr := ctx.RemoteAddr().String()

		e.skt2ctx.Delete(adrr)
		e.skt2key.Delete(adrr)
	}

	e.key2ctx.Delete(serviceKey)
}
